home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Snippets / DirectoryPopup 1.0 / □□□DPSample Source / FinderObjects.c next >
Text File  |  1996-06-03  |  5KB  |  198 lines

  1. /*
  2.  *    Project:        <none>
  3.  *
  4.  *    Filename:         FinderObjects.c
  5.  *
  6.  *    Author:         Marco Piovanelli
  7.  *
  8.  *    Revision History:
  9.  *
  10.  *            1996.06.02                MP        created this file
  11.  *
  12.  */
  13.  
  14.  
  15. #include "FinderObjects.h"
  16. #include "Utilities.h"
  17.  
  18. #ifndef __ALIASES__
  19. #include <Aliases.h>
  20. #endif
  21.  
  22. #ifndef __APPLEEVENTS__
  23. #include <AppleEvents.h>
  24. #endif
  25.  
  26. #ifndef __AEREGISTRY__
  27. #include <AERegistry.h>
  28. #endif
  29.  
  30. #ifndef __GESTALT__
  31. #include <Gestalt.h>
  32. #endif
  33.  
  34. enum
  35. {
  36.     kFinderType                =    'FNDR',
  37.     kFinderSignature        =    'MACS'
  38. } ;
  39.  
  40. OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN ) ;
  41. OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE ) ;
  42.  
  43. OSErr FindProcess ( OSType inProcessType, OSType inProcessSignature, ProcessSerialNumber * outPSN )
  44. {
  45.     ProcessInfoRec info ;
  46.     
  47.     // start at beginning of process list
  48.     outPSN -> lowLongOfPSN = kNoProcess ;
  49.     outPSN -> highLongOfPSN = kNoProcess ;
  50.  
  51.     // init process info record
  52.     BlockClear ( & info, sizeof ( info ) ) ;
  53.     info . processInfoLength = sizeof ( info ) ;
  54.     
  55.     // walk the process list, looking for the given creator
  56.     while (    ( GetNextProcess ( outPSN ) == noErr ) &&
  57.             ( GetProcessInformation ( outPSN, & info ) == noErr ) )
  58.     {
  59.         if ( ( info . processType == inProcessType ) && ( info . processSignature == inProcessSignature ) )
  60.         {
  61.             return noErr ;
  62.         }
  63.     }
  64.     
  65.     return procNotFound ;
  66. }
  67.  
  68. inline OSErr FinderPSN ( ProcessSerialNumber * outPSN )
  69. {
  70.     return FindProcess ( kFinderType, kFinderSignature, outPSN ) ;
  71. }
  72.  
  73. OSErr CreateFinderEvent ( AEEventClass inEventClass, AEEventID inEventID, AppleEvent * outAE )
  74. {
  75.     ProcessSerialNumber finderPSN ;
  76.     AEAddressDesc finderAddress ;
  77.     OSErr err ;
  78.  
  79.     InitDesc ( outAE ) ;
  80.     InitDesc ( & finderAddress ) ;
  81.  
  82.     //    find the process serial number of the Finder
  83.     if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
  84.         goto cleanup ;
  85.     
  86.     // create an address descriptor for the target application based on the PSN
  87.     if ( ( err = AECreateDesc ( typeProcessSerialNumber, & finderPSN, sizeof ( finderPSN ), & finderAddress ) ) != noErr )
  88.         goto cleanup ;
  89.     
  90.     // create the Apple event
  91.     if ( ( err = AECreateAppleEvent ( inEventClass, inEventID, & finderAddress, kAutoGenerateReturnID, kAnyTransactionID, outAE ) ) != noErr )
  92.         goto cleanup ;
  93.     
  94.     // clear result code
  95.     err = noErr;
  96.     
  97. cleanup:
  98.     ForgetDesc ( & finderAddress ) ;
  99.     return err ;
  100. }
  101.  
  102. static Boolean HasScriptableFinder ( void )
  103. {
  104.     SInt32 response ;
  105.     
  106.     return ( ( Gestalt ( gestaltFinderAttr, & response ) == noErr ) &&
  107.              ( response & ( 1L << gestaltOSLCompliantFinder ) ) ) ;
  108. }
  109.  
  110. OSErr OpenFinderObject ( const FSSpec * inThing )
  111. {
  112.     FSSpec thing = * inThing ;
  113.     AppleEvent ae, reply ;
  114.     AEDesc thingAlias, parentAlias, thingList ;
  115.     ProcessSerialNumber finderPSN ;
  116.     OSErr err ;
  117.     
  118.     InitDesc ( & ae ) ;
  119.     InitDesc ( & reply ) ;
  120.     InitDesc ( & thingAlias ) ;
  121.     InitDesc ( & parentAlias ) ;
  122.     InitDesc ( & thingList ) ;
  123.     
  124.     //    create a minimal alias for the specified object
  125.     if ( ( err = NewAliasMinimal ( & thing, ( AliasHandle * ) & thingAlias . dataHandle ) ) != noErr )
  126.         goto cleanup ;
  127.     thingAlias . descriptorType = typeAlias ;
  128.     
  129.     if ( HasScriptableFinder ( ) )
  130.     {
  131.         //    if the Finder is OSL-compliant, we can send it a
  132.         //    straightforward "open" (aevt/odoc) event
  133.         if ( ( err = CreateFinderEvent ( kCoreEventClass, kAEOpen, & ae ) ) != noErr )
  134.             goto cleanup ;
  135.  
  136.         //    the direct parameter of the event is simply the file alias
  137.         if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & thingAlias ) ) != noErr )
  138.             goto cleanup ;
  139.     }
  140.     else
  141.     {
  142.         //    older, non-OSL-compliant, Finders (from version 7.0 onward)
  143.         //    require a custom "open selection" event (FNDR/sope) with much
  144.         //    more complicated parameters
  145.     
  146.         if ( ( err = CreateFinderEvent ( kAEFinderEvents, kAEOpenSelection, & ae ) ) != noErr )
  147.             goto cleanup ;
  148.         
  149.         //    create a full alias for the parent directory (enclosing folder)
  150.         //    of specified object; if the object is at root level, create a full
  151.         //    alias for the object itself
  152.         if ( thing . parID != fsRtParID )
  153.         {
  154.             if ( ( err = FindParentSpec ( & thing ) ) != noErr )
  155.                 goto cleanup ;
  156.         }
  157.         if ( ( err = NewAlias ( nil, & thing, ( AliasHandle * ) & parentAlias . dataHandle ) ) != noErr )
  158.             goto cleanup ;
  159.         parentAlias . descriptorType = typeAlias;
  160.         
  161.         //    add the alias record for the parent directory to the Apple event, as direct object
  162.         if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, & parentAlias ) ) != noErr )
  163.             goto cleanup ;
  164.         
  165.         //    create a list of descriptors for the objects to show
  166.         if ( ( err = AECreateList ( nil, 0, false, & thingList ) ) != noErr )
  167.             goto cleanup ;
  168.         if ( ( err = AEPutDesc ( & thingList, 0, & thingAlias ) ) != noErr )
  169.             goto cleanup ;
  170.         
  171.         //    add the object list to the Apple event, as a keySelection parameter
  172.         if ( ( err = AEPutParamDesc ( & ae, keySelection, & thingList ) ) != noErr )
  173.             goto cleanup ;
  174.     }
  175.         
  176.     //    bring the Finder to the foreground
  177.     if ( ( err = FinderPSN ( & finderPSN ) ) != noErr )
  178.         goto cleanup ;
  179.     if ( ( err = SetFrontProcess ( & finderPSN ) ) != noErr )
  180.         goto cleanup ;
  181.     
  182.     //    send the apply event
  183.     if ( ( err = AESend ( & ae, & reply, kAENoReply + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil, nil ) ) != noErr )
  184.         goto cleanup ;
  185.  
  186.     //    clear result code
  187.     err = noErr ;
  188.  
  189. cleanup:
  190.     ForgetDesc ( & ae ) ;
  191.     ForgetDesc ( & reply ) ;
  192.     ForgetDesc ( & thingAlias ) ;
  193.     ForgetDesc ( & parentAlias ) ;
  194.     ForgetDesc ( & thingList ) ;
  195.     
  196.     return err ;
  197. }
  198.